﻿using HandyControl.Controls;
using HardToolApp.Model;
using HardToolApp.Tool;
using HardToolApp.View;
using NLua;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HardToolApp.ViewModel
{
    [ViewModelHelper("SPI从机", typeof(SPISlavePage), typeof(SPISlaveModel), Sort = 7)]
    internal class SPISlaveVM : CommVM
    {
        public SPISlaveVM() 
        {
            ScriptVM.register("spi_slave_set", "(数据长度,MSB,CPOL,CPHA)", "SPI_SLAVE", this.GetType(), "设置spi从机参数，数据长度0:8,1:16;MSB 0:高位在前,1低位在前;CPOL:0:CLK空闲时低电平,1:高电平;CPHA 0:第一个边沿采样,1:第二个边沿", "0:操作成功,1:操作失败");
            ScriptVM.register("spi_slave_send", "(发送数据,超时时间)", "SPI_SLAVE", this.GetType(),  "spi从机发送数据", "0:操作成功,1:操作失败");
            ScriptVM.register("spi_slave_send_byte", "(发送数据:byte数组,超时时间)", "SPI_SLAVE", this.GetType(), "spi从机发送数据", "0:操作成功,1:操作失败");
            ScriptVM.register("spi_slave_read", "(读取长度,超时时间)", "SPI_SLAVE", this.GetType(), "spi从机读取数据", "0:操作成功,1:操作失败");
            
        }
        // 接收
        public override void RecOkData(byte[] b)
        {
            switch (b[4])
            {
                case (byte)CommSubCmdSPISlave.COMM_SUB_SPI_SLAVE_READ://数据接收
                        ((SPISlaveModel)Model).receiveBytes = Common.Byte2String(b.Skip(6).ToArray(), len: b[2] - 7);
                        USBInfoVM.USBVm.AddMap((b[3] << 8) + b[4], Common.String2Byte(((SPISlaveModel)Model).receiveBytes));
                    break;
                default:
                        USBInfoVM.USBVm.AddMap((b[3] << 8) + b[4], 0);
                    break;
            }
            
        }
        #region SPISlave
        public static object spi_slave_set(byte dataSize,byte firstBit,byte CPOL,byte CPHA)
        {
            byte[] bytes = new byte[10];
            bytes[0] = 0x55;
            bytes[1] = 0xaa;
            bytes[2] = 10;
            bytes[3] = (byte)CommCmd.COMM_SPI_SLAVE;
            bytes[4] = (byte)CommSubCmdSPISlave.COMM_SUB_SPI_SLAVE_SET_PARAM;
            bytes[5] = (byte)dataSize;
            bytes[6] = (byte)firstBit;
            bytes[7] = (byte)CPOL;
            bytes[8] = (byte)CPHA;
            bytes[9] = Common.chksum(bytes);
            return USBInfoVM.USBVm.send(bytes);
        }

        public static object spi_slave_send(string sendBytes,UInt32 timeout)
        {
            byte[] data = Common.String2Byte(sendBytes);
            byte[] bytes = new byte[data.Count() + 10];
            bytes[0] = 0x55;
            bytes[1] = 0xaa;
            bytes[2] = (byte)(data.Count() + 10);
            bytes[3] = (byte)CommCmd.COMM_SPI_SLAVE;
            bytes[4] = (byte)CommSubCmdSPISlave.COMM_SUB_SPI_SLAVE_WRITE;
            bytes[5] = (byte)(timeout >> 24);
            bytes[6] = (byte)(timeout >> 16);
            bytes[7] = (byte)(timeout >> 8);
            bytes[8] = (byte)(timeout);
            data.CopyTo(bytes, 9);
            bytes[data.Count() + 9] = Common.chksum(bytes);
            return USBInfoVM.USBVm.send(bytes,(int)timeout+1000);
        }
        public static object spi_slave_send_byte(LuaTable sendBytes, UInt32 timeout)
        {
            byte[] data = Common.Lua2Byte(sendBytes);
            byte[] bytes = new byte[data.Count() + 10];
            bytes[0] = 0x55;
            bytes[1] = 0xaa;
            bytes[2] = (byte)(data.Count() + 10);
            bytes[3] = (byte)CommCmd.COMM_SPI_SLAVE;
            bytes[4] = (byte)CommSubCmdSPISlave.COMM_SUB_SPI_SLAVE_WRITE;
            bytes[5] = (byte)(timeout >> 24);
            bytes[6] = (byte)(timeout >> 16);
            bytes[7] = (byte)(timeout >> 8);
            bytes[8] = (byte)(timeout);
            data.CopyTo(bytes, 9);
            bytes[data.Count() + 9] = Common.chksum(bytes);
            return USBInfoVM.USBVm.send(bytes, (int)timeout + 1000);
        }

        public static object spi_slave_read(byte readLen,UInt32 timeout)
        {
            byte[] bytes = new byte[11];
            bytes[0] = 0x55;
            bytes[1] = 0xaa;
            bytes[2] = 11;
            bytes[3] = (byte)CommCmd.COMM_SPI_SLAVE;
            bytes[4] = (byte)CommSubCmdSPISlave.COMM_SUB_SPI_SLAVE_READ;
            bytes[5] = readLen;
            bytes[6] = (byte)(timeout >> 24);
            bytes[7] = (byte)(timeout >> 16);
            bytes[8] = (byte)(timeout >> 8);
            bytes[9] = (byte)(timeout);
            bytes[10] = Common.chksum(bytes);
            return USBInfoVM.USBVm.send(bytes,(int)timeout+1000);
        }
        /// <summary>
        /// 设置SPI参数
        /// </summary>
        /// <param name="m"></param>
        public override void Send(Peripheral peripheral)
        {
            SPISlaveModel m = (SPISlaveModel)peripheral;
            if (m.subCmd == (byte)Communicate.SubCmd.SetParam)
            {
                spi_slave_set((byte)m.dataSize, (byte)m.firstBit, (byte)m.CPOL, (byte)m.CPHA);
            }
            else if (m.subCmd == (byte)Communicate.SubCmd.SendData)
            {
                spi_slave_send(m.sendBytes,m.timeout);
            }
            else if (m.subCmd == (byte)Communicate.SubCmd.ReadData)
            {
                spi_slave_read(m.readLen,m.timeout);
            }
        }

        #endregion

    }
}
